package xgen;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.swing.*;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.io.PrintStream;
import java.util.Set;
import java.util.TreeSet;

public class Main {
    public static String outputEncoding = "GBK";
    static boolean noverify = false;
    // 检查显示获得锁
    static boolean explicitLockCheck = false;
    static Set<String> explicitLockIgnoreTables = new TreeSet<>();
    private static Xdb xdb;
    private static boolean useJson = false;
    private static boolean nowarn = false;
    private static String warn = "cfo";
    //--add for tranform. caijiacheng
    private static boolean transform = false;
    private static String srcdb = null;
    private static String destdb = null;

    private static void usage() {
        System.out.println("Usage: java -jar xgen.jar [options] xdb.xml");
        System.out.println("	-outputEncoding  encoding.");
        System.out.println("	-json            use json to store data.");
        System.out.println("	-output          output dir.");
        System.out.println("	-nowarn          do not print warning message.");
        System.out.println("	-warn [co]      select warning message. c=capacity, o=owner.");
        System.out.println("	-noverify        do not generate xbean verify code.");
        System.out.println("	-transform       for Tranform db");
        System.out.println("	-srcdb           tranform src db Dir. ");
        System.out.println("	-destdb          tranform dest db Dir. ");
        System.out.println("	-transformCheck  for check tranform is need to transform or not");
        System.out.println("	-explicitLockCheck [tale1:table2]  生成检查显示获得锁的代码, ");
        System.out.println("	                 其中：[]中冒号分隔的是忽略explicitLockCheck的表");
        System.out.println("	                       检查包括{add(fail),get,delete,remove} 不包括{add(success),insert,select}");
        Runtime.getRuntime().exit(1);
    }

    public static void _xdb_verify_(PrintStream ps, String prefix) {
        if (!noverify) {
            ps.println(prefix + "_xdb_verify_unsafe_();");
        }
    }

    public static void main(String[] args) throws Exception {
        System.setProperty("line.separator", "\n");
        String xdbxml = null;
        String xgenOutput = null;

        for (int i = 0; i < args.length; ++i) {
            if (args[i].equals("-outputEncoding")) {
                outputEncoding = args[++i];
            } else if (args[i].equals("-json")) {
                setUseJson(true);
            } else if (args[i].equals("-output")) {
                xgenOutput = args[++i];
            } else if (args[i].equals("-nowarn")) {
                nowarn = true;
            } else if (args[i].equals("-warn")) {
                if ((i + 1 < args.length) && !args[i + 1].startsWith("-")) {
                    warn = args[++i].toLowerCase();
                } else {
                    warn = ""; // select nothing
                }
            } else if (args[i].equals("-noverify")) {
                noverify = true;
            } else if (args[i].equals("-transform")) {
                transform = true;
            } else if (args[i].equals("-srcdb")) {
                srcdb = args[++i];
            } else if (args[i].equals("-destdb")) {
                destdb = args[++i];
            } else if (args[i].equals("-explicitLockCheck")) {
                explicitLockCheck = true;
                if ((i + 1 < args.length) && args[i + 1].startsWith("[")) {
                    ++i;
                    if (!args[i].startsWith("[") || !args[i].endsWith("]")) {
                        usage();
                    }
                    String[] ignoreTables = args[i].substring(1, args[i].length() - 1).split(":");
                    for (String ignoreTable : ignoreTables) {
                        if (ignoreTable.equals("")) {
                            continue;
                        }
                        explicitLockIgnoreTables.add(ignoreTable);
                    }
                }
            } else if (xdbxml == null) {
                xdbxml = args[i];
            } else {
                usage();
            }
        }

        if (null == xdbxml) {
            usage();
        }

        if (transform) {
            if (srcdb == null) {
                System.out.println("-srcdb need to been set!");
                usage();
            }
            if (destdb == null) {
                System.out.println("-destdb need to been set!");
                usage();
            }
        }

        Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xdbxml);
        Element root = doc.getDocumentElement();
        if (null != xgenOutput) {
            root.setAttribute("xgenOutput", xgenOutput);
        }
        try {
            xdb = new Xdb(root);
            xdb.compile();
            xdb.make();
            xdb.clean();
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, e);
            System.exit(1);
        }
    }

    static void warn(String msg, char type) {
        if (!nowarn && warn.indexOf(type) > -1) {
            System.err.println("WARN " + msg);
        }
    }

    static PrintStream openBeanFile(String classname) {
        File dir = xdb.getXbeandir();
        return fopen(dir, classname);
    }

    static PrintStream openBean__File(String classname) {
        File dir = xdb.getXbeandir__();
        return fopen(dir, classname);
    }

    static PrintStream openTableFile(String classname) {
        File dir = xdb.getXtabledir();
        return fopen(dir, classname);
    }

    static PrintStream fopen(File dir, String classname) {
        try {
            File file = new File(dir, classname + ".java");
            //System.out.println(file);
            return new PrintStream(new CachedFileOutputStream(file), false, outputEncoding);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String toUpper1(String name) {
        return name.substring(0, 1).toUpperCase() + name.substring(1);
    }

    public static String quote(String s) {
        return "\"" + s + "\"";
    }

    public static void verifyName(String name) {
        if (name.startsWith("_") && name.endsWith("_")) {
            throw new RuntimeException("Invalid Name of '" + name + "'. the name like '_*_' is reserved");
        }
    }

    static String getTransformSrcDb() {
        return srcdb;
    }

    static String getTransformDestDb() {
        return destdb;
    }

    public static boolean isUseJson() {
        return useJson;
    }

    public static void setUseJson(boolean useJson) {
        Main.useJson = useJson;
    }
}
